package gui;

import business.EventManager;
import business.Notifier;
import business.UserManager;
import business.WeatherForecastService;
import entity.AlertType;
import entity.Event;
import entity.NotificationType;
import entity.User;
import entity.WeatherAlert;
import javax.inject.Named;
import javax.enterprise.context.SessionScoped;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import javax.annotation.PostConstruct;
import javax.ejb.EJB;
import utils.DateService;
import utils.MessageCode;

@Named(value = "weatherAlertBean")
@SessionScoped
public class WeatherAlertBean implements Serializable {

    private final List<WeatherAlert> weatherAlerts = new ArrayList<>();
    private int sequence = 1;
    private int id;
    private WeatherAlert weatherAlert;

    @EJB
    private UserManager userManager;
    @EJB
    private EventManager eventManager;
    @EJB
    private WeatherForecastService weatherForecastService;
    @EJB
    private Notifier notifier;

    public WeatherAlertBean() {
    }

    @PostConstruct
    public void init() {
        User currentUser = userManager.getLoggedUser();
        Date now = new Date();
        for (Event event : currentUser.getCreatedEvents()) {
            if (event.getDate().after(now) && event.isOutdoor()
                    && event.getDate().before(DateService.threeDays())) {
                WeatherAlert alert = weatherForecastService.getWeatherAlert(event);
                if (alert != null) {
                    alert.setId(sequence++);
                    alert.setAlertType(AlertType.CREATOR);
                    Date date = weatherForecastService.getNextSuitableDate(event);
                    alert.setSuggestedDate(date);
                    weatherAlerts.add(alert);
                }
            }
        }
        for (Event event : currentUser.getJoiningEvents()) {
            if (event.getDate().after(now) && event.isOutdoor()
                    && event.getDate().before(DateService.tomorrow())) {
                WeatherAlert alert = weatherForecastService.getWeatherAlert(event);
                if (alert != null) {
                    alert.setId(sequence++);
                    alert.setAlertType(AlertType.PARTICIPANT);
                    weatherAlerts.add(alert);
                }
            }
        }
    }

    public void loadAlert() {
        for (WeatherAlert alert : weatherAlerts) {
            if (alert.getId() == id) {
                weatherAlert = alert;
                break;
            }
        }
    }

    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }

    public WeatherAlert getWeatherAlert() {
        if (weatherAlert == null) {
            weatherAlert = new WeatherAlert();
        }
        return weatherAlert;
    }

    public void setWeatherAlert(WeatherAlert weatherAlert) {
        this.weatherAlert = weatherAlert;
    }

    public boolean hasBadWeatherForecasts() {
        return !weatherAlerts.isEmpty();
    }

    public List<WeatherAlert> getWeatherAlerts() {
        return weatherAlerts;
    }

    public String ignore() {
        weatherAlerts.remove(weatherAlert);
        return "home?faces-redirect=true";
    }

    public String deleteEvent() {
        eventManager.delete(weatherAlert.getEvent());
        weatherAlerts.remove(weatherAlert);
        return "home?faces-redirect=true";
    }

    public String postpone() {
        Event event = eventManager.find(weatherAlert.getEvent().getEventId());
        event.setDate(weatherAlert.getSuggestedDate());
        eventManager.save(event);
        notifier.sendNotifications(event, NotificationType.MODIFICATION);
        weatherAlerts.remove(weatherAlert);
        return "log?faces-redirect=true&msgCode=" + MessageCode.EVENT_POSTPONED;
    }

    public String cancelParticipation() {
        User currentUser = userManager.getLoggedUser();
        Event event = null;
        if (weatherAlert != null && weatherAlert.getEvent() != null) {
            event = eventManager.find(weatherAlert.getEvent().getEventId());
        }
        if (event != null) {
            event.removeParticipant(currentUser);
            currentUser.getCalendars().get(0).removeEvent(event);
            userManager.save(currentUser);
            eventManager.save(event);
        }
        return "log?faces-redirect=true&msgCode=" + MessageCode.PARTICIPATION_CANCELLED;
    }
}
